#ifndef SOCKET_CAN_SOCKET_CAN_HPP
#define SOCKET_CAN_SOCKET_CAN_HPP


#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/can.h>
#include <linux/can/raw.h>
#include "system/Thread.h"

#include <linux/can/error.h>
//#include "m_can/canCallBack.h"

namespace socket_can
{


typedef void (*OnCanReadData)(can_frame &data);
class SocketCAN:public Thread
{
 public:
  SocketCAN(const char * ifname,int bitrate,int timeout = -1);

  ~SocketCAN();

  static SocketCAN* getInstance();

  void setFilter(can_filter* filterArray,int filterSize);

  bool is_connected();

  bool startup();

  bool stop();

  bool write(uint32_t frame_id, uint8_t dlc, uint8_t * data);


  virtual bool threadLoop();
  void setCanReadCb(OnCanReadData cb);

 private:

  void init();

  bool read(can_frame* canFrame);

  const char * ifname_;

  int socket_;

  bool connected_;

  long timeout_;

  int bitrate_;
  OnCanReadData CBCanRead_;
};
}

#define SOCKETCAN			socket_can::SocketCAN::getInstance()

#endif //SOCKET_CAN_SOCKET_CAN_HPP
